#ifndef __EV_SATELLITE_DATA_H__
#define __EV_SATELLITE_DATA_H__


#include<stdint.h>
#include<string>
#include"EvSatelliteCLData.hpp"
#include"EvSatelliteSIData.hpp"
#include"EvSatelliteORBData.hpp"
#include"rapidjson/document.h"

namespace SC_SUN
{

struct EvSatelliteData
{

    //////单星信息汇总//////

    /*
    长度：5位
    范围：1- SAT_NUM
    格式：SAT+XXXXX
    【SAT0000*】
    【SAT000**】
    【SAT00***】
    【SAT0****】
    【SAT*****】
    */
    std::string SAT_SN;                                     ///< 卫星创建序号

    /*
    长度：非固定
    格式：
    【satellite_星座名称_轨道面序号_面内序号】
    */
    std::string SAT_ID;                                     ///< 卫星ID

    double SAT_STP;                                         ///< 该星仿真步长,单位：秒
    double SAT_SQ;                                          ///< 该星数据维数,维度：n
    std::string PATH_SAT_SN;                                ///< 卫星文件夹地址和文件夹名

    //////单星信息//////
    std::string PATH_SAT_SI;                                ///< 单星信息文件地址和文件名
    std::string PATH_SAT_CL;                                ///< 模拟星钟文件地址和文件名
    std::string PATH_SAT_ORB;                               ///< 模拟轨道文件地址和文件名

    EvSatelliteSIData SAT_SI;                               ///< 单星信息
    EvSatelliteCLData SAT_CL;                               ///< 模拟星钟
    EvSatelliteORBData SAT_ORB;                             ///< 模拟轨道

    //卫星连接相关的
    std::vector<std::string> Parents;                       ///< 连接父节点
    std::vector<std::string> Children;                      ///< 连接子节点


rapidjson::Document ObjToJsonObject()
{
    using namespace rapidjson;
    Document doc;
    doc.SetObject();

    doc.AddMember(Value("SAT_SN", doc.GetAllocator()), Value(SAT_SN.data(), doc.GetAllocator()), doc.GetAllocator());
    doc.AddMember(Value("SAT_ID", doc.GetAllocator()), Value(SAT_ID.data(), doc.GetAllocator()), doc.GetAllocator());
    doc.AddMember(Value("SAT_STP", doc.GetAllocator()), Value(SAT_STP), doc.GetAllocator());
    doc.AddMember(Value("SAT_SQ", doc.GetAllocator()), Value(SAT_SQ), doc.GetAllocator());
    doc.AddMember(Value("PATH_SAT_SN", doc.GetAllocator()), Value(PATH_SAT_SN.data(), doc.GetAllocator()), doc.GetAllocator());

    doc.AddMember(Value("PATH_SAT_SI", doc.GetAllocator()), Value(PATH_SAT_SI.data(), doc.GetAllocator()), doc.GetAllocator());
    doc.AddMember(Value("SAT_SI", doc.GetAllocator()), SAT_SI.ObjToJsonObject(doc), doc.GetAllocator());

    doc.AddMember(Value("PATH_SAT_CL", doc.GetAllocator()), Value(PATH_SAT_CL.data(), doc.GetAllocator()), doc.GetAllocator());
    doc.AddMember(Value("SAT_CL", doc.GetAllocator()), SAT_CL.ObjToJsonObject(doc), doc.GetAllocator());

    doc.AddMember(Value("PATH_SAT_ORB", doc.GetAllocator()), Value(PATH_SAT_ORB.data(), doc.GetAllocator()), doc.GetAllocator());
    doc.AddMember(Value("SAT_ORB", doc.GetAllocator()), SAT_ORB.ObjToJsonObject(doc), doc.GetAllocator());

    Value value(kArrayType);
    for (int i = 0; i < Parents.size(); i++)
    {
        Value tmp(Parents[i].data(), doc.GetAllocator());
        value.PushBack(tmp, doc.GetAllocator());
    }
    //doc["Parents"] = value;
    doc.AddMember(Value("Parents", doc.GetAllocator()), value, doc.GetAllocator());

    Value value2(kArrayType);
    for (int i = 0; i < Children.size(); i++)
    {
        Value tmp(Parents[i].data(), doc.GetAllocator());
        value2.PushBack(tmp, doc.GetAllocator());
    }
    //doc["Children"] = value2;
    doc.AddMember(Value("Children", doc.GetAllocator()), value2, doc.GetAllocator());

    return doc;
}


static EvSatelliteData JsonToObj(rapidjson::GenericObject<true, rapidjson::Value> obj)
{
    using namespace rapidjson;
    EvSatelliteData ret;

    ret.SAT_SN = obj["SAT_SN"].GetString();
    ret.SAT_ID = obj["SAT_ID"].GetString();
    ret.SAT_STP = obj["SAT_STP"].GetDouble();
    ret.SAT_SQ = obj["SAT_SQ"].GetDouble();
    ret.PATH_SAT_SN = obj["PATH_SAT_SN"].GetString();

    ret.PATH_SAT_SI = obj["PATH_SAT_SI"].GetString();
    ret.SAT_SI = EvSatelliteSIData::JsonObjectToObject(obj["SAT_SI"].GetObj());

    ret.PATH_SAT_CL = obj["PATH_SAT_CL"].GetString();
    ret.SAT_CL = EvSatelliteCLData::JsonObjectToObject(obj["SAT_CL"].GetObj());

    ret.PATH_SAT_ORB = obj["PATH_SAT_ORB"].GetString();
    ret.SAT_ORB = EvSatelliteORBData::JsonObjectToObject(obj["SAT_ORB"].GetObj());

    auto array1 = obj["Parents"].GetArray();
    for (int i = 0; i < array1.Size(); i++)
    {
        ret.Parents.push_back(array1[i].GetString());
    }

    auto array2 = obj["Children"].GetArray();
    for (int i = 0; i < array2.Size(); i++)
    {
        ret.Children.push_back(array2[i].GetString());
    }

    return ret;
}


static EvSatelliteData JsonToObj(const rapidjson::Document& doc)
{
    using namespace rapidjson;
    auto obj = doc.GetObj();
    return JsonToObj(obj);
}


static EvSatelliteData JsonToObj2(rapidjson::GenericObject<false, rapidjson::Value> obj)
{
    using namespace rapidjson;
    EvSatelliteData ret;

    ret.SAT_SN = obj["SAT_SN"].GetString();
    ret.SAT_ID = obj["SAT_ID"].GetString();
    ret.SAT_STP = obj["SAT_STP"].GetDouble();
    ret.SAT_SQ = obj["SAT_SQ"].GetDouble();
    ret.PATH_SAT_SN = obj["PATH_SAT_SN"].GetString();

    ret.PATH_SAT_SI = obj["PATH_SAT_SI"].GetString();
    ret.SAT_SI = EvSatelliteSIData::JsonObjectToObject2(obj["SAT_SI"].GetObj());

    ret.PATH_SAT_CL = obj["PATH_SAT_CL"].GetString();
    ret.SAT_CL = EvSatelliteCLData::JsonObjectToObject2(obj["SAT_CL"].GetObj());

    ret.PATH_SAT_ORB = obj["PATH_SAT_ORB"].GetString();
    ret.SAT_ORB = EvSatelliteORBData::JsonObjectToObject2(obj["SAT_ORB"].GetObj());

    auto array1 = obj["Parents"].GetArray();
    for (int i = 0; i < array1.Size(); i++)
    {
        ret.Parents.push_back(array1[i].GetString());
    }

    auto array2 = obj["Children"].GetArray();
    for (int i = 0; i < array2.Size(); i++)
    {
        ret.Children.push_back(array2[i].GetString());
    }

    return ret;
}

};

}


#endif